package com.campsys.config;

import com.campsys.config.filter.AjaxAuthenticationFilter;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authc.pam.AuthenticationStrategy;
import org.apache.shiro.authc.pam.FirstSuccessfulStrategy;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.authz.ModularRealmAuthorizer;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Configuration
public class ShiroConfig {
    
    @Bean
    public UserRealm userRealm() {
        return new UserRealm();
    }
    
    @Bean("authenticator")
    public ModularRealmAuthenticator authenticator() {
        ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();
        authenticator.setAuthenticationStrategy(new FirstSuccessfulStrategy());
        return authenticator;
    }
    
    @Bean("authorizer")
    public ModularRealmAuthorizer authorizer() {
        ModularRealmAuthorizer authorizer = new ModularRealmAuthorizer();
        return authorizer;
    }
    
    @Bean
    public SecurityManager securityManager(
            UserRealm userRealm, 
            SessionManager sessionManager, 
            ModularRealmAuthenticator authenticator,
            ModularRealmAuthorizer authorizer) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(userRealm);
        securityManager.setSessionManager(sessionManager);
        securityManager.setAuthenticator(authenticator);
        securityManager.setAuthorizer(authorizer);
        return securityManager;
    }
    
    @Bean
    public SessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        // 设置自定义的SessionId名称
        SimpleCookie sessionIdCookie = new SimpleCookie("CAMP-SESSIONID");
        sessionIdCookie.setHttpOnly(true);
        sessionIdCookie.setPath("/");
        sessionManager.setSessionIdCookie(sessionIdCookie);
        
        // 禁用URL重写
        sessionManager.setSessionIdUrlRewritingEnabled(false);
        
        return sessionManager;
    }
    
    @Bean("shiroFilterFactoryBean")
    public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);
        
        Map<String, String> filterMap = new LinkedHashMap<>();
        
        // 登录相关接口完全放行
        filterMap.put("/login", "anon");
        filterMap.put("/logout", "anon");
        
        // 静态资源匿名访问
        filterMap.put("/static/**", "anon");
        
        // 超级管理员权限配置
        filterMap.put("/root/**", "authc,roles[root]");
        
        // 活动管理员权限配置
        filterMap.put("/admin/**", "authc,roles[admin]");
        
        // 教师权限配置
        filterMap.put("/teacher/**", "authc,roles[teacher]");
        
        // 学生权限配置
        filterMap.put("/student/learning/**", "authc,roles[student]");
        
        // 其他所有请求需要认证
        filterMap.put("/**", "authc");
        
        shiroFilter.setFilterChainDefinitionMap(filterMap);
        return shiroFilter;
    }
    
    @Bean
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }
    
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }
} 